from typing import Annotated, Optional

from fastapi import APIRouter, Query
from fastapi_pagination import Page
from fastapi_pagination.ext.tortoise import paginate
from pydantic import UUID4

from .filters import GalleryCategoryFilter, GalleryFilter
from .models import GalleryCategory, Gallery
from .schemas import (
    GalleryOutSchema,
    GalleryCategoryOutSchema,
    GalleryCategoryEditSchema,
    GalleryEditSchema,
    GalleryFilters,
)
from utils.auth import public_route

router = APIRouter()


@router.get("/category", response_model=Page[GalleryCategoryOutSchema])
async def get_gallery_category_list(
    name: Optional[str] = Query(None),
    active: Optional[bool] = Query(None),
) -> Page[GalleryCategoryOutSchema]:
    query = GalleryCategory.all()
    query = GalleryCategoryFilter.filter(query, {"name": name, "active": active})
    return await paginate(query)


@router.get("/category/list_select_options")
async def get_gallery_category_list_select_options():
    query = GalleryCategory.filter(active=True)
    data = await query.all()
    return [{"label": item.name, "value": item.id} for item in data if item.active]


@router.get(
    "/category/public",
    response_model=list[GalleryCategoryOutSchema],
)
@public_route()
async def get_gallery_category_list_no_auth():
    query = GalleryCategory.filter(active=True)
    return await query.all()


@router.post("/category", response_model=GalleryCategoryOutSchema)
async def create_gallery_category(data: GalleryCategoryEditSchema):
    obj = await GalleryCategory.create(**data.model_dump())
    return obj


@router.put("/category/{category_id}", response_model=GalleryCategoryOutSchema)
async def update_gallery_category(category_id: UUID4, data: GalleryCategoryEditSchema):
    obj = await GalleryCategory.get_or_raise(id=category_id)
    await obj.update_from_dict(data.model_dump(exclude_unset=True))
    await obj.save()
    return obj


@router.delete("/category/batch_delete")
async def batch_delete_gallery_category(category_ids: list[UUID4]):
    await GalleryCategory.filter(id__in=category_ids).delete()
    return None


@router.delete("/category/{category_id}")
async def delete_gallery_category(category_id: UUID4):
    obj = await GalleryCategory.get_or_raise(id=category_id)
    await obj.delete()
    return None


@router.get("/public", response_model=Page[GalleryOutSchema])
@public_route()
async def get_public_gallery_list() -> Page[GalleryOutSchema]:
    query = (
        Gallery.filter(active=True).order_by("-created_at").prefetch_related("category")
    )
    return await paginate(query)


@router.get("", response_model=Page[GalleryOutSchema])
async def get_gallery_list(filter_query: Annotated[GalleryFilters, Query()]):
    query = Gallery.all().prefetch_related("category")
    query = GalleryFilter.filter(query, filter_query)
    return await paginate(query)


@router.post("", response_model=GalleryOutSchema)
async def create_gallery(data: GalleryEditSchema):
    obj = await Gallery.create(
        **data.model_dump(exclude={"category_id"}), category_id=data.category_id
    )
    return await Gallery.get(id=obj.id).prefetch_related("category")


@router.delete("/batch_delete")
async def batch_delete_gallery(gallery_ids: list[UUID4]):
    await Gallery.filter(id__in=gallery_ids).delete()
    return None


@router.put("/{gallery_id}", response_model=GalleryOutSchema)
async def update_gallery(gallery_id: UUID4, data: GalleryEditSchema):
    obj = await Gallery.get_or_raise(id=gallery_id)
    await obj.update_from_dict(data.model_dump(exclude_unset=True))
    await obj.save()
    return await Gallery.get(id=gallery_id).prefetch_related("category")


@router.delete("/{gallery_id}")
async def delete_gallery(gallery_id: UUID4):
    obj = await Gallery.get_or_raise(id=gallery_id)
    await obj.delete()
    return None
